/*
 * @Author: Nxf
 * @Date: 2024-05-17 08:53:22
 * @LastEditors: Nxf
 * @LastEditTime: 2024-05-17 08:53:33
 * @Descripttion:
 */
// axios 的标准配置
// 封装为函数
// 允许由 odoojs-jsonrpc 配置:
// 1. baseURL, timeout
// 2. 请求头中 配置 session_id
// 3. 截获响应头, 处理 session_id
// 4. 对响应结果做 额外处理
// 5. 对 响应 error, 自行处理

import axios from 'axios'

function get_window() {
  try {
    return window
  } catch (error) {
    return undefined
  }
}

export class Request {
  constructor(payload) {
    const { baseURL, timeout = 500000, messageError } = payload
    this._service = this._get_service({ baseURL, timeout, messageError })
  }

  localStorage = {
    getItem(item) {
      const win = get_window()
      if (win) {
        return win.localStorage.getItem(item)
      } else {
        return undefined
      }
    },
    setItem(item, val) {
      const win = get_window()
      if (win) {
        win.localStorage.setItem(item, val)
      }
    }
  }

  _get_service({ baseURL, timeout, messageError }) {
    const service = axios.create({
      baseURL,
      withCredentials: true,
      timeout
    })

    service.interceptors.request.use(
      config => {
        // 这里 在请求头中 增加 session_id
        const session_id = Request._sid
        if (session_id) {
          config.headers['X-Openerp-Session-Id'] = session_id
        }
        return config
      },
      error => {
        console.log('request config error') // for debug
        if (messageError) {
          return messageError(error)
        } else {
          return Promise.reject(error)
        }
      }
    )

    service.interceptors.response.use(
      response => {
        const url = response.config.url
        const url_auth = '/web/session/authenticate'
        const url_info = '/web/session/get_session_info'
        const url_destroy = '/web/session/destroy'

        if (url === url_auth || url === url_info) {
          // if run test or run from wx miniprograme, not cookie,
          // so wo set sid to call odoo
          // console.log('===url:', url)
          // console.log('===response:', response)

          const headers2 = response.headers
          const cookie = headers2['set-cookie']
          // const cookie = headers2['Set-Cookie']

          // console.log('===headers2:', headers2)
          // console.log('===cookie:', cookie)
          if (cookie) {
            const cookie2 = cookie[0]
            const session_id = cookie2.slice(11, 51)
            // console.log('===session_id:', session_id)
            Request._sid = session_id
          }
        } else if (url === url_destroy) {
          Request._sid = undefined
        }

        return response
      },
      error => {
        const url = (error.config || {}).url
        const url_check = '/web/session/check'
        const url_info = '/web/session/get_session_info'
        const url_destroy = '/web/session/destroy'

        console.log('request response error', error) // for debug
        if ([url_check, url_info, url_destroy].includes(url)) {
          return Promise.reject(error)
        } else if (messageError) {
          return messageError(error)
        } else {
          return Promise.reject(error)
        }
      }
    )

    return service
  }

  call_post(url, data) {
    return this._service({ url, method: 'post', data })
  }
}

Request._sid = undefined
